using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;

namespace ProgrammingLanguageNr1
{
	public class FunctionSymbol : Symbol, Scope
	{
		public FunctionSymbol (Scope enclosingScope, string name, SprakType type, AST functionDefinitionNode) 
			: base(name, type)
		{
			Assert.IsNotNull(functionDefinitionNode);
			
			m_enclosingScope = enclosingScope;
			m_functionDefinitionNode = functionDefinitionNode;
		}
		
		public virtual Scope getEnclosingScope() {
			return m_enclosingScope;
		}
		
		public virtual Symbol resolve(string name) {
			if (m_symbols.ContainsKey(name)) {
				return m_symbols[name];
			} 
			else if (m_enclosingScope != null) {
				return m_enclosingScope.resolve(name);
			} 
			else {
				throw new InvalidOperationException("Can't resolve symbol with name \"" + name + "\"");
			}
		}
		
		public virtual void define(Symbol symbol) {
			m_symbols.Add(symbol.getName(), symbol);
		}
		
		public virtual bool isDefined(String symbolName) {
			return m_symbols.ContainsKey(symbolName);
		}
		
		public override string ToString() {
			StringBuilder text = new StringBuilder();
			text.Append(getName() + ": ");
			int i = 0;
			foreach(KeyValuePair<string, Symbol> pair in m_symbols) {
				if(i != 0) { text.Append(", "); } else { i++; }
				text.Append(pair.Value.ToString());
			}
			return text.ToString();
		}
		
		public AST getFunctionDefinitionNode() { return m_functionDefinitionNode; }
		
		protected Dictionary<string, Symbol> m_symbols = new Dictionary<string, Symbol>();
		protected Scope m_enclosingScope;
		protected AST m_functionDefinitionNode;
	}
}

